/*
 to compress...
 d:
 cd TalkTalk\piecesofuk\Javascript
 java -jar D:\Programming\Javascript\yuicompressor-2.3.5\build\yuicompressor-2.3.5.jar calendar.js -o calendar.min.js
*/

// short URL to calendar.html ... http://bit.ly/poukCAL


/* TODO
  test 2007, make sure intermediate years/month heads shown etc
  DONE:cbl view - load month when clicked
  allow text search : &q=searchTerm
   "*  When creating a query, list search terms separated by spaces, in the form q=term1 term2 term3. (As with all of the query parameter values, the spaces must be URL encoded.) The service returns all entries that match all of the search terms (like using AND between terms). Like Google's web search, a service searches on complete words (and related words with the same stem), not substrings.
    * To search for an exact phrase, enclose the phrase in quotation marks: q="exact phrase".
    * To exclude entries that match a given term, use the form q=-term.
    * The search is case-insensitive.
    * Example: to search for all entries that contain the exact phrase "Elizabeth Bennet" and the word "Darcy" but don't contain the word "Austen", use the following query: ?q="Elizabeth Bennet" Darcy -Austen"
    http://code.google.com/apis/gdata/docs/2.0/reference.html
*/

/* BUGS
  FIXED:Calendar is looping when clicking "latest" from "twitter"
*/

if (typeof PIECESOFUK == "undefined") {
	var PIECESOFUK = {};
}

PIECESOFUK.allSongs = null;

/*
PIECESOFUK.albumMap = {"POY" : "Pieces of You",
                       "Spirit" : "Spirit",
											 "ThisWay" : "This Way",
											 "0304" : "0304",
											 "GBAIW" : "Goodbye Alice In Wonderland",
											 "PC" : "Perfectly Clear",
											 "Other" : "Other",
											 "unreleased" : "unreleased",
											 "not found" : "not found"}
*/

PIECESOFUK.loadSongs = function() {
  $.ajax({
    type: "GET",
    url: "Data/songData.js",
    dataType: "script",
	  async: false,
    success: function(){

    },
    error: function(obj, msg){
			PIECESOFUK.songs = null;
      alert( "Unable to load songs database. Please try later. Error: " + msg );
    }
  });  // $.ajax
}

PIECESOFUK.initCalendar = function() { // only called from calendar.html

	if ( PIECESOFUK.feeds == undefined ) PIECESOFUK.feeds = new Array;
  PIECESOFUK.feeds["calendar"] = new PIECESOFUK.calendar();

	setTimeout(PIECESOFUK.controller, 1000);
  $("body").show();
	$(".aView, .aControl, .aDialog").hide();
	PIECESOFUK.initCalendarView();
}

PIECESOFUK.initCalendarView = function() {
	$("#calView, #calControls").show();

	this.focus = function() {
		$(".aControl").hide();
		$("#calControls").show();
	}
  $("#calView").dialog({title: "calendar", width: 657, height: $(window).height() - 10, focus: this.focus});
	$("#ui-dialog-title-calView")
			   .prepend('<img class="infoViewTitleImg" src="Graphics/calendar.gif" width="15" height="14" alt="icon">')
         .parent()
				 .css("paddingLeft", "3px");

  $("#calView").parent().css("padding", "0px");
//  $("#calView").css("padding", "0px");
  $("#calView").parent().css("top", "34px");

 	$("#calendarLink").click( function() {
	  $("#menu").hide();
	  $(".aControl").hide();
	  $("#calView").show();
	  $("#calControls").show();
	  if (PIECESOFUK.feeds["calendar"] == undefined) PIECESOFUK.feeds["calendar"] = new PIECESOFUK.calendar();
	  else {
		  if ($("#calView").dialog("isOpen")) $("#calView").dialog("moveToTop");
		  else {
		    $("#calView").dialog("open");
		  }
	  }
	  return false;
  });

   $("#calChartsIcon, #visualizationsLink").click(function() {
     if (PIECESOFUK.visualizationsPtr == null) PIECESOFUK.visualizationsPtr = new PIECESOFUK.visualizations();
	  else {
		  if ($("#visualizations").dialog("isOpen")) $("#visualizations").dialog("moveToTop");
		  else $("#visualizations").dialog("open");
	  }
    PIECESOFUK.visualizationsPtr.calendarCharts();
		return false;
  });

//  PIECESOFUK.feeds["calendar"].suspend();

}

PIECESOFUK.calendar = function() {
  this.name = "calendar";
  var calendar = this;

  this.calViewMode = "Month";
  this.gMonth = PIECESOFUK.todayMM, this.gYear = PIECESOFUK.todayYYYY;
  this.maxMM = null;
  this.maxYYYY = null; // initalised on first google calendar load
  this.minMM = 01;
//  this.minYYYY = 2008;
//  this.minYYYY = 2007;
  this.minYYYY = 2006;

  this.initialise = function() {
		calendar.setStatus("initialised");
  }

	this.focus = function() {
		$(".aControl").hide();
		$("#calControls").show();
	}

//TODO change load and initialRead functions into  loadRange and readRange functions?
// or maybe just change the callback to a readRange function

  this.load = function() {
    calendar.setStatus("loading");
// doesn't work when calendar not in view    $("#calView").height($(window).height()-105);
    if (calendar.calViewMode == "Month") $("#week3day3 > .cbmContentDiv").append(PIECESOFUK.$preloader);
//    $("#calControls").width( $("#cbmView").width() +5 );
//    $("#cblView").width( $("#cbmView").width()).hide();
    $("#cblView").hide();
    $("#calSelectView").val("Month");
    $("#calSelectMonth").val(calendar.gMonth);
    $("#calSelectYear").val(calendar.gYear);
    var startMinMM = PIECESOFUK.todayMM; // future events only
    var startMinYYYY = PIECESOFUK.todayYYYY;
    startMinMM = (startMinMM < 10 ? "0" + startMinMM : startMinMM);
    var startMinDD = "01";
	  theURL =
	    "http://www.google.com/calendar/feeds/"
	    + "o75curq5sg0qvg313odgfgg9ec%40group.calendar.google.com"
	    + "/public/full-noattendees"
	    + "?orderby=starttime"
	    + "&alt=json-in-script"
	    + "&callback=?"
	    + "&singleevents=true"
	    + "&sortorder=ascending"
	    + "&futureevents=false"
      + "&max-results=100"
	    + "&start-min=" + startMinYYYY + "-" + startMinMM + "-" + startMinDD + "T00:00:00"
    $.getJSON(theURL, calendar.initialRead);
  }


  this.initialRead = function(json) {
    $("#week3day3 > .cbmContentDiv").html("");
    if (json.feed.entry === undefined) {
      calendar.setStatus("failed");
    // ought to do something here
      return;
    }
    var currentDD = 0, currentMM = 0, currentYYYY = 0;
    var ddCount = 0;

    for (var i = 0; i < json.feed.entry.length; i++) {
	    var calItem = json.feed.entry[i];
      var theTime = "", splitDate;
	    if (calItem.gd$when[0].startTime.search(/T/) == -1) {
	      splitDate = calItem.gd$when[0].startTime.match(/(\d{4})[-](\d{2})[-](\d{2})/);
      } else {
		    splitDate = calItem.gd$when[0].startTime.match(/(\d{4})[-](\d{2})[-](\d{2})[T](\d{2})[:](\d{2})[:](\d{2})/);
		    theTime = splitDate[4] + ":" + splitDate[5];
	    }
		  var theYYYY = splitDate[1];
		  var theMM = splitDate[2];
		  var theDD = splitDate[3];
// new stuff for storing latest data
// what do we want?
// anything this week
// anything new from today onwards
			var $latest = null;
			var	theDate = new Date(theYYYY, theMM-1, theDD);
			var MMn = parseInt( theMM, 10);
			var DDn = parseInt( theDD, 10);
			var tooFar = false; // if too far in future then don't want unless it's new
			if (theDate.valueOf() >= PIECESOFUK.today.valueOf() ) {
				$latest = $("<div/>").addClass("latestItem");
				var latestText = "";
			  if (theDate.valueOf() == PIECESOFUK.today.valueOf() ) latestText = "Today";
			  else if (theDate.valueOf() == PIECESOFUK.today.valueOf() + PIECESOFUK.aDay) latestText = "Tomorrow";
			  else if (theDate.valueOf() <= PIECESOFUK.today.valueOf() + PIECESOFUK.aWeek) latestText = PIECESOFUK.dayText[theDate.getDay()];
			  else {
					latestText = DDn + " " + PIECESOFUK.months[MMn - 1];
					tooFar = true;
				}
				latestText += " " + theTime + calItem.title.$t.slice(5);
				if ( calItem.title.$t.slice(2,4) == "TV" ) latestText += ", " + calItem.gd$where[0].valueString;
				$latest.append(latestText);
		    var splitDate = calItem.updated.$t.match(/(\d{4})[-](\d{2})[-](\d{2})[T](\d{2})[:](\d{2})[:](\d{2})/);
		    var theDate = new Date(splitDate[1], splitDate[2] - 1, splitDate[3]);
				if (PIECESOFUK.nowVal - theDate.valueOf() < PIECESOFUK.aWeek) $("<span/>").addClass("latestNew").text(" new!").appendTo($latest);
				else if (tooFar) $latest = null;
			}
// was the event created within a week


// end new stuff for storing latest data

      if (currentYYYY != theYYYY) {
        calendar.createFullYear(theYYYY, $("#cblView"), "append");
        currentYYYY = theYYYY;
        currentMM = theMM;
        currentDD = theDD;
        ddCount = 0;
        var $dayDIVHead = $("<div/>").attr("id", "d" + theDD + "m" + theMM + "y" + theYYYY).addClass("cblDayHead").text(theDD);
        var $dayDIV  = $("<div/>");
        $("#m" + theMM + "y" + theYYYY).next().append($dayDIVHead, $dayDIV);
        if ( $("#m" + theMM + "y" + theYYYY).hasClass("cblInitialised") ) {
          $("#m" + theMM + "y" + theYYYY).removeClass("cblInitialised").removeAttr("title").addClass("cblLoaded");
        }
      } else if (currentMM != theMM) {
        while (++currentMM < theMM) {
          $("#m" + (currentMM < 10 ? "0" + currentMM : currentMM) + "y" + currentYYYY)
            .removeClass("cblInitialised").addClass("cblNodata").next().text("no events found");
        }
        currentMM = theMM;
        currentDD = theDD;
        ddCount = 0;
        var $dayDIVHead = $("<div/>").attr("id", "d" + theDD + "m" + theMM + "y" + theYYYY).addClass("cblDayHead").text(theDD);
        var $dayDIV  = $("<div/>");
        $("#m" + theMM + "y" + theYYYY).next().append($dayDIVHead, $dayDIV);
        if ( $("#m" + theMM + "y" + theYYYY).hasClass("cblInitialised") ) {
          $("#m" + theMM + "y" + theYYYY).removeClass("cblInitialised").removeAttr("title").addClass("cblLoaded");
        }

      } else if (currentDD != theDD) {
        ddCount = 0;
        currentDD = theDD;
        var $dayDIVHead = $("<div/>").attr("id", "d" + theDD + "m" + theMM + "y" + theYYYY).addClass("cblDayHead").text(theDD);
        var $dayDIV  = $("<div/>");
        $("#m" + theMM + "y" + theYYYY).next().append($dayDIVHead, $dayDIV);
			}
      var $entryDIV = $("<div/>").addClass("cblEntry").attr("title", calItem.content.$t)
					.data("where", calItem.gd$where[0].valueString)
          .text(theTime + calItem.title.$t.slice(5) + ", " + calItem.gd$where[0].valueString);
			if ( calItem.title.$t.slice(2,4) == "LV" ) $entryDIV.addClass("aConcert");
			if ($latest) $entryDIV.data("latest", $latest);
      if (++ddCount % 2 == 0) $entryDIV.addClass("cblEntryEven");
      $("#d" + theDD + "m" + theMM + "y" + theYYYY).next().append($entryDIV);
    }
    calendar.maxMM = parseInt(currentMM, 10); calendar.maxYYYY = currentYYYY;
    var firstTime = true;
    while (++currentMM <= 12) {
    // TODO don't think this will work if split over two years
      if (firstTime) {
        firstTime = false;
        $("#m" + (currentMM < 10 ? "0" + currentMM : currentMM) + "y" + currentYYYY)
                           .removeClass("cblInitialised").removeAttr("title").addClass("cblNodata").next().text("no further events");
      } else $("#m" + (currentMM < 10 ? "0" + currentMM : currentMM) + "y" + currentYYYY)
                           .removeClass("cblInitialised").removeAttr("title").addClass("cblNodata");
    }
    calendar.setStatus("loaded");
  }

  this.addEvents = function() {
    $("#calPrevLink").click( function() {
			if ($("#calView").dialog("isOpen")) $("#calView").dialog("moveToTop");
			else $("#calView").dialog("open");

      var gMonthSav = calendar.gMonth; gYearSav = calendar.gYear;
      if (--calendar.gMonth == 0) {
        calendar.gMonth = 12; --calendar.gYear;
      }
      if (calendar.gYear == calendar.minYYYY && calendar.gMonth < calendar.minMM || calendar.gYear < calendar.minYYYY) {
        calendar.gMonth = gMonthSav; calendar.gYear = gYearSav;
      } else {
        $("#calSelectMonth").val(calendar.gMonth);
        $("#calSelectYear").val(calendar.gYear);
        if (calendar.calViewMode == "List") {
          calendar.cblView(calendar.gMonth, calendar.gYear);
        }
        else calendar.cbmView(calendar.gMonth, calendar.gYear);
      }
      return false;
    });
    $("#calNextLink").click( function() {
			if ($("#calView").dialog("isOpen")) $("#calView").dialog("moveToTop");
			else $("#calView").dialog("open");

      var gMonthSav = calendar.gMonth; gYearSav = calendar.gYear;
      if (++calendar.gMonth > 12) {
        calendar.gMonth = 1; ++calendar.gYear;
      }
      if (calendar.gYear == calendar.maxYYYY && calendar.gMonth > calendar.maxMM || calendar.gYear > calendar.maxYYYY) {
        calendar.gMonth = gMonthSav; calendar.gYear = gYearSav;
      } else {
        $("#calSelectMonth").val(calendar.gMonth);
        $("#calSelectYear").val(calendar.gYear);

        if (calendar.calViewMode == "List") {
          calendar.cblView(calendar.gMonth, calendar.gYear);
        }
        else calendar.cbmView(calendar.gMonth, calendar.gYear);
      }
      return false;
    });

    $("#calGoButton").click( function() { // need to disable the GO button in list mode or move to month mode????
			if ($("#calView").dialog("isOpen")) $("#calView").dialog("moveToTop");
			else $("#calView").dialog("open");

      var gMonthSav = calendar.gMonth; gYearSav = calendar.gYear;
      calendar.gMonth =  $("#calSelectMonth").val();
      calendar.gYear =  $("#calSelectYear").val();
      if ( calendar.gYear == calendar.minYYYY && calendar.gMonth < calendar.minMM || calendar.gYear < calendar.minYYYY) {
        alert("Out of Range: too far in the past!");
        calendar.gMonth = gMonthSav; calendar.gYear = gYearSav;
        $("#calSelectMonth").val(calendar.gMonth);
        $("#calSelectYear").val(calendar.gYear);
      } else  if (calendar.gYear == calendar.maxYYYY && calendar.gMonth > calendar.maxMM || calendar.gYear > calendar.maxYYYY) {
        alert("Out of Range: too far in the future");
        calendar.gMonth = gMonthSav; calendar.gYear = gYearSav;
        $("#calSelectMonth").val(calendar.gMonth);
        $("#calSelectYear").val(calendar.gYear);
      } else {
        if (calendar.calViewMode == "List") {
          calendar.cblView(calendar.gMonth, calendar.gYear);
          return false;
        }
        calendar.cbmView(calendar.gMonth, calendar.gYear);
      }
      return false;
    });

    $("#calSelectView").change( function() {
			if ($("#calView").dialog("isOpen")) $("#calView").dialog("moveToTop");
			else $("#calView").dialog("open");

      if ($(this).val() == "Month") {
        calendar.calViewMode = "Month";
        $("#cblView").hide();
        $("#cbmView").show();
        calendar.cbmView(calendar.gMonth, calendar.gYear);
      } else {
        calendar.calViewMode = "List";
        $("#cblView").show();
        $("#cbmView").hide();
        calendar.cblView(calendar.gMonth, calendar.gYear);
      }
    });
  }

  this.display = function() {
    calendar.cbmView(PIECESOFUK.todayMM, PIECESOFUK.todayYYYY);
    calendar.setStatus("complete");
    this.addEvents();
  }

  this.resetCbmView = function() {
    $("#d" + PIECESOFUK.todayDDx).removeClass("cbmToday");
    $("#week6").show();
    $("#week5").show();
  }

  this.cbmView = function(mm, yyyy) {
// id's are in the form ...   y9999    m99y9999   d99m99y9999
    if ( (typeof mm == "number" && mm < 10) || (typeof mm == "string" && mm.length == 1) ) mm = "0" + mm;
    theID = "#m" + mm + "y" + yyyy;
    var $mmYYYY = $(theID);
    if ($mmYYYY.length == 0 || $mmYYYY.hasClass("cblInitialised")) {
      calendar.loadNewMonth(mm, yyyy);
      return;
    }
    var actualMM = mm;
    calendar.resetCbmView();
    --mm // mm is offset 0;
    $("#cbmMonthHead").text(PIECESOFUK.months[mm] + " " + yyyy);
    $(document).scrollTop(0)
    var aDate = new Date(yyyy, mm, 1);
    if (PIECESOFUK.isLeapYear(yyyy)) PIECESOFUK.daysInMonth[1] = 29;
    else PIECESOFUK.daysInMonth[1] = 28;
    var day = aDate.getDay();
    for (var i = 0; i < day; i++) {
      $("#week1day"+i + " > .cbmDateDiv").html("&nbsp;").removeClass("cbmDateSet").next().removeAttr("id").html("");
    }
    maxDays = PIECESOFUK.daysInMonth[mm];
    var week = 1;
    var date = 0;
    while (++date <= maxDays) {
      var dateStr = (date < 10 ? "0" + date : date);
      $("#week"+week+"day"+day + " > .cbmDateDiv").text(date).addClass("cbmDateSet")
              .next().attr("id", "d" + dateStr).html("");
      if (++day > 6) {
        ++week;
        day = 0;
      }
    }
    if (week == 5 || (week == 6 && day == 0)) $("#week6").hide();
    if (week == 5 && day == 0) $("#week5").hide();
    --day;
    while (++day <= 6) {
      $("#week" + week + "day"+day + " > .cbmDateDiv").html("&nbsp;").removeClass("cbmDateSet")
          .next().removeAttr("id").html("");
    }
    if (actualMM == PIECESOFUK.todayMM && yyyy == PIECESOFUK.todayYYYY) $("#d"+PIECESOFUK.todayDDx).addClass("cbmToday"); // highlight today;
    $mmYYYY.next().children(".cblDayHead").each( function() {
      var dd = $(this).attr("id").slice(1,3);
      $(this).next().children().each( function() {
        var fullText = $(this).text() + ", " + $(this).attr("title");
        var $anEntry = $("<div/>")
				  .addClass("cbmEntry")
					.text($(this).text())
					.data("where", $(this).data("where"))
					.css("width", $("#d"+dd).parent().css("width") )
          .attr("title", fullText);
				if ($(this).hasClass("aConcert")) $anEntry.addClass("aConcert");
        $("#d"+dd).append($anEntry);
      });
    });
//    window.location.hash = "cbmView";
    $("#calView").scrollTop( $("#calView").scrollTop() + ( $("#cbmView").offset().top - $("#calView").offset().top));

  }

  this.cblView = function(mm, yyyy) {
    if ( (typeof mm == "number" && mm < 10) || (typeof mm == "string" && mm.length == 1) ) mm = "0" + mm;
    theID = "#m" + mm + "y" + yyyy;
    var $mmYYYY = $(theID);
    if ($mmYYYY.length == 0 || $mmYYYY.hasClass("cblInitialised")) {
      calendar.loadNewMonth(mm, yyyy);
      return;
    }
    var jumpPoint = "#m" + (calendar.gMonth < 10 ? "0" + calendar.gMonth : calendar.gMonth) + "y" + calendar.gYear;
//    window.location.hash = jumpPoint;
    $("#calView").scrollTop( $("#calView").scrollTop() + ($(jumpPoint).offset().top - $("#calView").offset().top));

//???    $(document).scrollTop( $(document).scrollTop() - 30 );
  }

  this.googleCalReadMonth = function(json) {
    $("#week3day3 > .cbmContentDiv").html("");
    if (json.feed.entry === undefined) {
      // ought to do something here
      return;
    }
    var currentDD = 0;
    var ddCount = 0;
    for (var i = 0; i < json.feed.entry.length; i++) {
  	  var calItem = json.feed.entry[i];
      var theTime = "", splitDate;
  	  if (calItem.gd$when[0].startTime.search(/T/) == -1) {
  	    splitDate = calItem.gd$when[0].startTime.match(/(\d{4})[-](\d{2})[-](\d{2})/);
      } else {
  		  splitDate = calItem.gd$when[0].startTime.match(/(\d{4})[-](\d{2})[-](\d{2})[T](\d{2})[:](\d{2})[:](\d{2})/);
  		  theTime = splitDate[4] + ":" + splitDate[5];
  	  }
  		var theYYYY = splitDate[1];
  		var theMM = splitDate[2];
  		var theDD = splitDate[3];
      $monthDIV = $("#m" + theMM + "y" + theYYYY).next();
      if (currentDD != theDD) {
        if (currentDD != 0) {
          $monthDIV.append($dayDIVHead, $dayDIV);
        }
        currentDD = theDD;
        ddCount = 0;
        var $dayDIVHead = $("<div/>").attr("id", "d" + theDD + "m" + theMM + "y" + theYYYY).addClass("cblDayHead").text(theDD);
        var $dayDIV = $("<div/>");
      }
      var $entryDIV = $("<div/>").addClass("cblEntry").attr("title", calItem.content.$t)
					.data("where", calItem.gd$where[0].valueString)
//			    .data("eventDate", calItem.gd$when[0].startTime)
//					.data("updateDate", calItem.updated.$t)
              .text(theTime + calItem.title.$t.slice(5) + ", " + calItem.gd$where[0].valueString);
			if ( calItem.title.$t.slice(2,4) == "LV" ) $entryDIV.addClass("aConcert");
      if (++ddCount % 2 == 0) $entryDIV.addClass("cblEntryEven");
      $dayDIV.append($entryDIV);
    }
    $("#m" + theMM + "y" + theYYYY).removeClass("cblInitialised").removeAttr("title").addClass("cblLoaded");
    $monthDIV.append($dayDIVHead, $dayDIV);
    if (calendar.calViewMode == "List") {
      $("#cblPreloader").remove();
      calendar.cblView(theMM, theYYYY);
    }
    else calendar.cbmView(theMM, theYYYY);
  }

  this.loadNewMonth = function(month, year) {
  // month must be 2 characters
    if ( (typeof month == "number" && month < 10) ||
        (typeof month == "string" && month.length == 1) ) month = "0" + month;

    if (! $("#y" + year).length) { // the year hasn't been created yet
      calendar.createFullYear(year, $("#cblView"), "prepend"); // TODO need to amend for more years
    } else if (! $("#m" + month + "y" + year).length ) {
        var $monthDIVHead = $("<div/>").attr("id", "m" + month + "y" + year).addClass("cblMonthHead").text(PIECESOFUK.months[month - 1]);
        var $monthDIV = $("<div/>");
        $("#y" + year).next().append($monthDIVHead, $monthDIV);
    }
    if (calendar.calViewMode == "Month") $("#week3day3 > .cbmContentDiv").append(PIECESOFUK.$preloader);
    else {
      $("#calView").scrollTop( $("#calView").scrollTop() + ( $("#m" + month + "y" + year).offset().top - $("#calView").offset().top));
      $("#m" + month + "y" + year).append(PIECESOFUK.$cblPreloader);
      var padding = (( $("#m" + month + "y" + year).width() - PIECESOFUK.$cblPreloader.width() )/2) - 20;
      PIECESOFUK.$cblPreloader.css("paddingLeft", padding + "px");
    }

    var startMinMM = startMaxMM = month;
    var startMinYYYY = startMaxYYYY = year;
    var startMinDD = "01";

    if (PIECESOFUK.isLeapYear(startMaxYYYY)) PIECESOFUK.daysInMonth[1] = 29;
    else PIECESOFUK.daysInMonth[1] = 28;

    var startMaxDD = PIECESOFUK.daysInMonth[startMaxMM-1];

  	theURL =
	    "http://www.google.com/calendar/feeds/"
	    + "o75curq5sg0qvg313odgfgg9ec%40group.calendar.google.com"
	    + "/public/full-noattendees"
	    + "?orderby=starttime"
	    + "&alt=json-in-script"
	    + "&callback=?"
	    + "&singleevents=true"
	    + "&sortorder=ascending"
	    + "&futureevents=false"
      + "&max-results=60"
	    + "&start-min=" + startMinYYYY + "-" + startMinMM + "-" + startMinDD + "T00:00:00"
	    + "&start-max=" + startMaxYYYY + "-" + startMaxMM + "-" + startMaxDD + "T23:59:59";
      $.getJSON(theURL, calendar.googleCalReadMonth);
  }


// month classes: initialised, loaded, nodata, error,
  this.createFullYear = function(year, $appendPoint, howToAppend) {
		year = parseInt(year, 10);
    var $yearDIVHead = $("<div/>").attr("id", "y" + year).addClass("cblYearHead").text(year);
    var $yearDIV = $("<div/>");
    for (var mm = 1; mm <= 12; mm++ ) {
      var $monthDIVHead = $("<div/>").attr("id", "m" + (mm < 10 ? "0" + mm : mm) + "y" + year)
        .addClass("cblMonthHead cblInitialised")
			  .attr("title", "click to load month")
			  .text(PIECESOFUK.months[mm - 1]).attr("name", "m" + (mm < 10 ? "0" + mm : mm) + "y" + year);
      var $monthDIV = $("<div/>");
      $yearDIV.append($monthDIVHead, $monthDIV);
    }
    if (howToAppend == "append") {
      $appendPoint.append($yearDIVHead, $yearDIV);
    } else
    if (howToAppend == "prepend") {
      $appendPoint.prepend($yearDIVHead, $yearDIV);
    }

		$(".cblInitialised").click( function() {
			$(this).unbind("click");
			var id = $(this).attr("id");
			calendar.gMonth = parseInt( id.slice(1,3), 10);
			calendar.gYear = id.slice(4,8);
      $("#calSelectMonth").val(calendar.gMonth);
      $("#calSelectYear").val(calendar.gYear);
			calendar.loadNewMonth( calendar.gMonth, calendar.gYear );
		});

		if ( year + 1 < calendar.maxYYYY && !$("#y" + year + 1).length) calendar.createFullYear( year + 1, $("#y" + year).next(), "append");
  } // end PIECESOFUK.createFullYear


//	calendar.initialise();

}

PIECESOFUK.calendar.prototype = new PIECESOFUK.feed();
